package com.zlict.commonelasticsearch.utils;

import com.zlict.commonelasticsearch.domain.AuditLog;
import com.zlict.commonelasticsearch.service.ElasticsearchAuditService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import jakarta.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * 审计日志工具类
 * 
 * @author zlict
 */
@Component
public class AuditLogUtils {

    @Autowired
    private ElasticsearchAuditService elasticsearchAuditService;

    /**
     * 记录审计日志
     * 
     * @param actionType 操作类型
     * @param actionResult 操作结果
     * @param details 详细信息
     */
    public void recordAuditLog(String actionType, String actionResult, String details) {
        try {
            AuditLog auditLog = new AuditLog();
            
            // 获取当前请求信息
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attributes != null) {
                HttpServletRequest request = attributes.getRequest();
                
                // 设置用户信息（这里简化处理，实际项目中需要从安全上下文获取）
                String username = getCurrentUsername();
                Long userId = getCurrentUserId();
                auditLog.setUsername(username);
                auditLog.setUserId(userId);
                
                // 设置IP地址
                String ipAddress = getClientIpAddress(request);
                auditLog.setIpAddress(ipAddress);
                
                // 设置用户代理信息
                String userAgentString = request.getHeader("User-Agent");
                if (userAgentString != null && !userAgentString.isEmpty()) {
                    auditLog.setUserAgent(userAgentString);
                    auditLog.setDeviceInfo(parseDeviceInfo(userAgentString));
                }
            }
            
            // 设置操作信息
            auditLog.setActionType(actionType);
            auditLog.setActionResult(actionResult);
            auditLog.setDetails(details);
            auditLog.setActionTime(new Date());
            auditLog.setCreateTime(new Date());
            
            // 保存到Elasticsearch
            saveToElasticsearch(auditLog);
            
        } catch (Exception e) {
            // 记录审计日志失败时，不影响主业务流程
            System.err.println("记录审计日志失败: " + e.getMessage());
        }
    }

    /**
     * 记录载体相关操作的审计日志
     * 
     * @param operation 操作类型
     * @param carrierInfo 载体信息
     * @param result 操作结果
     */
    public void recordCarrierOperation(String operation, String carrierInfo, String result) {
        String actionType = "载体管理-" + operation;
        String details = String.format("操作类型: %s, 载体信息: %s", operation, carrierInfo);
        recordAuditLog(actionType, result, details);
    }

    /**
     * 记录登录相关审计日志
     * 
     * @param username 用户名
     * @param actionType 操作类型
     * @param actionResult 操作结果
     * @param details 详细信息
     */
    public void recordLoginAuditLog(String username, String actionType, String actionResult, String details) {
        try {
            AuditLog auditLog = new AuditLog();
            
            // 获取当前请求信息
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attributes != null) {
                HttpServletRequest request = attributes.getRequest();
                
                // 设置用户信息
                auditLog.setUsername(username);
                auditLog.setUserId(null); // 登录时用户ID可能为空
                
                // 设置IP地址
                String ipAddress = getClientIpAddress(request);
                auditLog.setIpAddress(ipAddress);
                
                // 设置用户代理信息
                String userAgentString = request.getHeader("User-Agent");
                if (userAgentString != null && !userAgentString.isEmpty()) {
                    auditLog.setUserAgent(userAgentString);
                    auditLog.setDeviceInfo(parseDeviceInfo(userAgentString));
                }
            }
            
            // 设置操作信息
            auditLog.setActionType("登录-" + actionType);
            auditLog.setActionResult(actionResult);
            auditLog.setDetails(details);
            auditLog.setActionTime(new Date());
            auditLog.setCreateTime(new Date());
            
            // 保存到Elasticsearch
            saveToElasticsearch(auditLog);
            
        } catch (Exception e) {
            // 记录审计日志失败时，不影响主业务流程
            System.err.println("记录登录审计日志失败: " + e.getMessage());
        }
    }
    
    /**
     * 记录账号锁定审计日志
     * 
     * @param username 用户名
     * @param retryCount 错误次数
     * @param maxRetryCount 最大错误次数
     * @param lockTime 锁定时间（分钟）
     */
    public void recordAccountLockAuditLog(String username, int retryCount, int maxRetryCount, int lockTime) {
        String details = String.format("用户 %s 因密码错误次数达到 %d 次（当前错误次数: %d），账号被锁定 %d 分钟", 
            username, maxRetryCount, retryCount, lockTime);
        recordLoginAuditLog(username, "账号锁定", "失败", details);
    }
    
    /**
     * 记录密码错误审计日志
     * 
     * @param username 用户名
     * @param retryCount 当前错误次数
     * @param maxRetryCount 最大错误次数
     */
    public void recordPasswordErrorAuditLog(String username, int retryCount, int maxRetryCount) {
        String details = String.format("用户 %s 密码错误，当前错误次数: %d/%d", username, retryCount, maxRetryCount);
        recordLoginAuditLog(username, "密码验证", "失败", details);
    }
    
    /**
     * 保存审计日志到Elasticsearch
     * 
     * @param auditLog 审计日志对象
     */
    private void saveToElasticsearch(AuditLog auditLog) {
        try {
            // 构建用户标识（优先使用用户名，其次是用户ID）
            String userIdentifier = auditLog.getUsername();
            if (userIdentifier == null || userIdentifier.isEmpty()) {
                if (auditLog.getUserId() != null) {
                    userIdentifier = auditLog.getUserId().toString();
                } else {
                    userIdentifier = "unknown";
                }
            }
            
            // 构建操作类型
            String operation = auditLog.getActionType();
            
            // 构建操作结果
            String result = auditLog.getActionResult();
            
            // 构建详细信息（包含IP、设备信息等）
            StringBuilder detailsBuilder = new StringBuilder();
            if (auditLog.getDetails() != null && !auditLog.getDetails().isEmpty()) {
                detailsBuilder.append(auditLog.getDetails());
            }
            if (auditLog.getIpAddress() != null && !auditLog.getIpAddress().isEmpty()) {
                if (detailsBuilder.length() > 0) {
                    detailsBuilder.append(", ");
                }
                detailsBuilder.append("IP地址: ").append(auditLog.getIpAddress());
            }
            if (auditLog.getDeviceInfo() != null && !auditLog.getDeviceInfo().isEmpty()) {
                if (detailsBuilder.length() > 0) {
                    detailsBuilder.append(", ");
                }
                detailsBuilder.append("设备信息: ").append(auditLog.getDeviceInfo());
            }
            
            String details = detailsBuilder.toString();
            
            // 保存到Elasticsearch
            elasticsearchAuditService.saveAuditLog(userIdentifier, operation, result, details);
            
        } catch (Exception e) {
            // Elasticsearch保存失败不影响主业务流程
            System.err.println("保存审计日志到Elasticsearch失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取当前用户名（简化实现）
     */
    private String getCurrentUsername() {
        // 这里需要根据实际项目的安全框架来实现
        // 例如从 SecurityContext 或 JWT Token 中获取
        return "system";
    }
    
    /**
     * 获取当前用户ID（简化实现）
     */
    private Long getCurrentUserId() {
        // 这里需要根据实际项目的安全框架来实现
        return 1L;
    }
    
    /**
     * 获取客户端IP地址
     */
    private String getClientIpAddress(HttpServletRequest request) {
        String xForwardedFor = request.getHeader("X-Forwarded-For");
        if (xForwardedFor != null && !xForwardedFor.isEmpty() && !"unknown".equalsIgnoreCase(xForwardedFor)) {
            return xForwardedFor.split(",")[0].trim();
        }
        
        String xRealIp = request.getHeader("X-Real-IP");
        if (xRealIp != null && !xRealIp.isEmpty() && !"unknown".equalsIgnoreCase(xRealIp)) {
            return xRealIp;
        }
        
        return request.getRemoteAddr();
    }
    
    /**
     * 解析设备信息
     */
    private String parseDeviceInfo(String userAgent) {
        // 简化的设备信息解析
        if (userAgent.contains("Windows")) {
            return "Windows";
        } else if (userAgent.contains("Mac")) {
            return "Mac";
        } else if (userAgent.contains("Linux")) {
            return "Linux";
        } else if (userAgent.contains("Android")) {
            return "Android";
        } else if (userAgent.contains("iPhone") || userAgent.contains("iPad")) {
            return "iOS";
        }
        return "Unknown";
    }
}




